/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2024
 *
 * 本程序是自由软件；您可以根据自由软件基金会发布的GNU通用公共许可证
 * 第2版来重新发布和/或修改本程序；
 *
 * 本程序的发布是希望它能发挥作用，但不提供任何保证；甚至不包含
 * 对适销性或特定用途适用性的暗示保证。详见GNU通用公共许可证
 * 获取更多细节。
 *
 * 您应该已收到GNU通用公共许可证的副本；如果没有，请写信给
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef DGRV2_DYNAMIC_PRIORITY_QUEUE_DISC_H
#define DGRV2_DYNAMIC_PRIORITY_QUEUE_DISC_H

#include "ns3/boolean.h"
#include "ns3/data-rate.h"
#include "ns3/nstime.h"
#include "ns3/queue-disc.h"
#include "ns3/random-variable-stream.h"
#include "ns3/traced-value.h"

namespace ns3
{

class TraceContainer;

/**
 * \ingroup traffic-control
 * \class DGRv2DynamicPriorityQueueDisc
 * \brief 基于剩余时间动态调整优先级的队列调度器
 */
class DGRv2DynamicPriorityQueueDisc : public QueueDisc
{
  public:
    /**
     * \brief 获取TypeId
     * \return 对象的TypeId
     */
    static TypeId GetTypeId(void);

    /**
     * \brief DGRv2DynamicPriorityQueueDisc构造函数
     */
    DGRv2DynamicPriorityQueueDisc();

    /**
     * \brief DGRv2DynamicPriorityQueueDisc析构函数
     */
    virtual ~DGRv2DynamicPriorityQueueDisc();

    /**
     * \brief 获取队列状态
     * \return 队列状态
     */
    uint32_t GetQueueStatus(void);

    /**
     * \brief 获取队列延迟
     * \return 队列延迟
     */
    double GetQueueDelay(void);

    // 在DGRv2DynamicPriorityQueueDisc类的public部分添加以下方法
    size_t GetMaxSizePriority0(void) const
    {
        return m_maxSize[0];
    }

    void SetMaxSizePriority0(size_t value)
    {
        m_maxSize[0] = value;
    }

    size_t GetMaxSizePriority1(void) const
    {
        return m_maxSize[1];
    }

    void SetMaxSizePriority1(size_t value)
    {
        m_maxSize[1] = value;
    }

    size_t GetMaxSizePriority2(void) const
    {
        return m_maxSize[2];
    }

    void SetMaxSizePriority2(size_t value)
    {
        m_maxSize[2] = value;
    }

    size_t GetMaxSizePriority3(void) const
    {
        return m_maxSize[3];
    }

    void SetMaxSizePriority3(size_t value)
    {
        m_maxSize[3] = value;
    }

    size_t GetMaxSizePriority4(void) const
    {
        return m_maxSize[4];
    }

    void SetMaxSizePriority4(size_t value)
    {
        m_maxSize[4] = value;
    }

    // 丢弃数据包的原因
    static constexpr const char* LIMIT_EXCEEDED_DROP = "队列容量超过限制";

  private:
    virtual bool DoEnqueue(Ptr<QueueDiscItem> item);
    virtual Ptr<QueueDiscItem> DoDequeue(void);
    virtual Ptr<const QueueDiscItem> DoPeek(void) const;
    virtual bool CheckConfig(void);
    virtual void InitializeParams(void);

    /**
     * \brief 根据剩余时间对数据包进行分类
     * \param item 要分类的数据包
     * \return 数据包的队列索引
     */
    uint32_t EnqueueClassify(Ptr<QueueDiscItem> item);

    // 队列参数
    uint32_t m_maxSize[5];     //!< 各优先级队列的最大容量
    uint32_t m_currentSize[5]; //!< 各优先级队列的当前容量
    double m_queueDelay;       //!< 估计的队列延迟
    bool m_useDynamicPriority; //!< 是否使用基于剩余时间的动态优先级
    Time m_queueDelayRef;      //!< 参考队列延迟
};

} // namespace ns3

#endif /* DGRV2_DYNAMIC_PRIORITY_QUEUE_DISC_H */
